from zhipuai import ZhipuAI

import inspect
import json
import pandas as pd
from typing import List,Callable
import math
import re

api_key = "4956db3da95d43eab77efa6937882679.Xm27NhBWZPJE3ORb"
client = ZhipuAI(api_key=api_key)

# response = client.chat.completions.create(model="glm-4",
#                                messages=[{"role":"user","content":"请介绍下自己"}])
# print(response)

def auto_functions(fun_list:List[Callable]) -> List[dict]:
    tool_description = []
    for fun in fun_list:
        # 获取函数的签名信息
        sign = inspect.signature(fun)
        func_param = sign.parameters

        # 函数的参数描述
        parameters = {
            "type":"object",
            "properties":{},
            "required":[]
        }

        for param_name,param in func_param.items():
            # 添加参数描述和类型
            parameters["properties"][param_name] = {
                "description":param.annotation.__doc__ if param.annotation is not inspect._empty else "",
                "type":str(param.annotation) if param.annotation != param.empty else "Any"
            }
            # 如果参数有默认值，那么它不是必须的
            if param.default != param.empty:
                parameters["required"].append(param_name)

        # 函数描述字典
        func_dict = {
            "type":"function",
            "function":{
                "name":fun.__name__,
                "description":fun.__doc__.strip(),
                "parameters":parameters
            }
        }

        tool_description.append(func_dict)

    return tool_description

def test_inspect(name:int):
    """
    测试inspect函数
    :param name: 名字
    :return:
    """
    print("hello")

# function_list = [test_inspect]
#
# result = auto_functions(function_list)
# print(result)

def machine_learning_1():
    """
    解释机器学习是什么
    """
    answer = """机器学习是人工智能的一个分支，研究计算机如何自动从数据中学习，提升性能并做出预测。\
        它通过算法让计算机提炼知识，优化任务执行，而无需明确编程。"""

    return answer

def machine_learning_2():
    """描述一下机器学习和深度学习的区别"""

    answer = """机器学习涉及算法从数据中学习模式以做出预测或决策，涵盖广泛的技术，包括监督、非监督和强化学习。\
        深度学习是机器学习的一个子集，专注于使用神经网络，尤其是深层神经网络，来处理复杂的数据结构，\
        实现高级功能如图像识别和自然语言理解，其特点是多层次的抽象和自动特征学习。"""

    return answer

function_list = [machine_learning_1,machine_learning_2]

# 获取函数描述的 JSON 字典
tools = auto_functions(function_list)
print(tools)

# 将函数列表转换为字典
avaiable_functions = {func.__name__: func for func in function_list}

## 打印大模型识别到的外部函数的名字
def function_call_test(prompt,tools):
    message = [
        {"role": "user", "content": prompt}
    ]
    response = client.chat.completions.create(model="glm-4",
                                              messages=message,
                                              tools=tools,
                                              tool_choice="auto")
    return response

# resp = function_call_test("请问机器学习是什么",tools)
# print(resp)
#
# resp1 = function_call_test("请问深度学习和机器学习的区别是什么",tools)
# print(resp1)
#
# resp2 = function_call_test("请问深度学习是什么",tools)
# print(resp2)

#在选择进行功能选择前，让模型先判断被提到的问题是否在它的资料库中
def function_call_new(prompt,tools):
    judge_words = '这个问题的答案是否在你的语料库里?请回答"这个问题在我的语料库里"或者"这个问题不在我的语料库里",不要回答其他额外的文字'
    messages = [{"role":"user","content":prompt+judge_words}]
    res = client.chat.completions.create(model="glm-4",
                                         messages=messages)

    con = res.choices[0].message.content
    print(con)
    messages = [{"role": "user", "content": prompt}]
    if "这个问题在我的语料库里" in con:
        response = client.chat.completions.create(model="glm-4",
                                                  messages=messages)
    else:
        response = client.chat.completions.create(model="glm-4",
                                                  messages=messages,
                                                  tools=tools,
                                                  tool_choice="auto")

    print(response.choices[0].message.content)

# function_call_new("请问机器学习是什么",tools)

#以下是基于不同数学运算类型的七个函数示例：

def add(a: float, b: float) -> float:
    """
    计算两个浮点数的和。

    参数:
    a (float): 第一个加数。
    b (float): 第二个加数。

    返回:
    float: 两个参数的和。
    """
    return a + b

def subtract(a: float, b: float) -> float:
    """
    计算两个浮点数的差。

    参数:
    a (float): 被减数。
    b (float): 减数。

    返回:
    float: 两个参数的差。
    """
    return a - b

def multiply(a: float, b: float) -> float:
    """
    计算两个浮点数的乘积。

    参数:
    a (float): 第一个乘数。
    b (float): 第二个乘数。

    返回:
    float: 两个参数的乘积。
    """
    return a * b

def divide(a: float, b: float) -> float:
    """
    计算两个浮点数的商。

    参数:
    a (float): 被除数。
    b (float): 除数。注意：除数不能为0。

    返回:
    float: 两个参数的商。
    """
    if b == 0:
        raise ValueError("除数不能为0")
    return a / b

def power(a: float, b: float) -> float:
    """
    计算第一个浮点数的幂运算结果。

    参数:
    a (float): 底数。
    b (float): 指数。

    返回:
    float: 底数的指数幂。
    """
    return a ** b

function_account_list = [add,subtract,multiply,divide,power]

tools3 = auto_functions(function_account_list)
print(tools3)

avaiable_account_function = {func.__name__:func for func in function_account_list}

def function_account_call(prompt,tools):
    messages = [{"role":"user","content":prompt}]
    res = client.chat.completions.create(model="glm-4",
                                  messages=messages,
                                  tools=tools,
                                  tool_choice="auto")
    print(res)
    resp_function = res.choices[0].message.tool_calls[0].function
    function_to_call = avaiable_account_function[resp_function.name]
    function_args = json.loads(resp_function.arguments)
    function_res = function_to_call(**function_args)

    messages.append({"role":"tool",
                     "name":resp_function.name,
                     "content":prompt+str(function_res)})
    final_resp = client.chat.completions.create(model="glm-4",
                                                messages=messages,
                                                tools=tools,
                                                tool_choice=resp_function.name)
    return print(final_resp.choices[0].message.content)
# prompt = "请帮我计算一下 56565656 乘以 34343 等于几"
# result = function_account_call(prompt,tools3)

chuan_prompt = "请问1234567与7654321的和与积作差等于几？"
message = []
message.append({
    "role":"user",
    "content":chuan_prompt+ "解决这个问题要分几步？\
                                                     记住只告诉我步骤，不要解决问题，也不要说额外的话\
                                                     请按照'1. xxx;2. xxx;...;的格式列举\
                                                     步骤与步骤之间使用半角分号;相隔，整个句子请用半角分号;结尾"
})

resp_step = client.chat.completions.create(model="glm-4",
                                           messages=message,
                                           temperature=0.1)
print(resp_step.choices[0].message.content)

print("=============================================================")

step_content = resp_step.choices[0].message.content

# 定义正则表达式模式
pattern = r'(.*?;)'

steps = re.findall(pattern,step_content)

steps = [step.strip() for step in steps if step.strip()]

step_answer = ""

for step in steps:
    print(step)
    message = [{"role":"assistant","content":chuan_prompt+"正在分步骤解决问题，已知条件是"+step_answer}]
    message.append({"role":"user","content":"当前步骤是"+step})
    resp_re_step = client.chat.completions.create(model="glm-4",
                                                  messages=message)


